from pydantic import BaseModel, Field, ConfigDict, field_validator
from typing import Optional
import re


class SystemConfigCreate(BaseModel):
    """
    创建系统配置的请求模型
    """
    smtp_server: Optional[str] = Field(default='smtp.qq.com', description='SMTP服务器')
    smtp_port: Optional[int] = Field(default=587, description='SMTP端口')
    email: Optional[str] = Field(default=None, description='邮箱账户')
    email_password: Optional[str] = Field(default=None, description='邮箱密码（明文入参，入库加密）')
    phone_number: Optional[str] = Field(default=None, description='手机号')
    douyin_password: Optional[str] = Field(default=None, description='抖音登录密码（明文入参，入库加密）')
    xhs_cookie: Optional[str] = Field(default=None, description='小红书登录Cookie（明文入参，入库加密）')
    is_active: bool = Field(default=True, description='是否为当前生效配置')

    @field_validator('email')
    def validate_email(cls, v):
        """
        校验邮箱格式
        """
        if v is None or v == "":
            return v
        pattern = r"^[^@\s]+@[^@\s]+\.[^@\s]+$"
        if not re.match(pattern, v):
            raise ValueError('邮箱格式不正确')
        return v

    @field_validator('phone_number')
    def validate_phone(cls, v):
        """
        校验手机号或座机格式
        """
        if v is None or v == "":
            return v
        mobile = r"^\d{11}$"
        landline = r"^\d{3,4}-?\d{7,8}$"
        if not (re.match(mobile, v) or re.match(landline, v)):
            raise ValueError('电话格式不正确')
        return v

    @field_validator('smtp_port')
    def validate_port(cls, v):
        """
        校验端口范围
        """
        if v is None:
            return 587
        if not (1 <= int(v) <= 65535):
            raise ValueError('端口范围应为1-65535')
        return v


class EmailSendRequest(BaseModel):
    """
    发送邮件请求模型
    """
    to: str = Field(..., description='收件人邮箱')
    subject: str = Field(..., description='邮件主题')
    body: str = Field(..., description='邮件正文')

    @field_validator('to')
    def validate_to(cls, v):
        """
        校验收件人邮箱格式
        """
        import re
        pattern = r"^[^@\s]+@[^@\s]+\.[^@\s]+$"
        if not re.match(pattern, v):
            raise ValueError('收件人邮箱格式不正确')
        return v


class SystemConfigUpdate(BaseModel):
    """
    更新系统配置的请求模型（全部字段可选）
    """
    smtp_server: Optional[str] = None
    smtp_port: Optional[int] = None
    email: Optional[str] = None
    email_password: Optional[str] = None
    phone_number: Optional[str] = None
    douyin_password: Optional[str] = None
    xhs_cookie: Optional[str] = None
    is_active: Optional[bool] = None

    @field_validator('email')
    def validate_email(cls, v):
        """
        校验邮箱格式
        """
        if v is None or v == "":
            return v
        pattern = r"^[^@\s]+@[^@\s]+\.[^@\s]+$"
        if not re.match(pattern, v):
            raise ValueError('邮箱格式不正确')
        return v

    @field_validator('phone_number')
    def validate_phone(cls, v):
        """
        校验手机号或座机格式
        """
        if v is None or v == "":
            return v
        mobile = r"^\d{11}$"
        landline = r"^\d{3,4}-?\d{7,8}$"
        if not (re.match(mobile, v) or re.match(landline, v)):
            raise ValueError('电话格式不正确')
        return v

    @field_validator('smtp_port')
    def validate_port(cls, v):
        """
        校验端口范围
        """
        if v is None:
            return v
        if not (1 <= int(v) <= 65535):
            raise ValueError('端口范围应为1-65535')
        return v


class SystemConfigResponse(BaseModel):
    """
    系统配置响应模型（敏感字段脱敏显示）
    """
    id: int
    smtp_server: str
    smtp_port: int
    email: Optional[str]
    email_password: str = Field(..., description='脱敏显示')
    phone_number: Optional[str]
    douyin_password: str = Field(..., description='脱敏显示')
    xhs_cookie: str = Field(..., description='脱敏显示')
    is_active: bool
    created_at: str = Field(..., description='创建时间')
    updated_at: str = Field(..., description='更新时间')

    model_config = ConfigDict(from_attributes=True)

    @classmethod
    def from_orm(cls, obj):
        """
        从 ORM 对象创建响应模型，并对敏感字段进行脱敏
        """
        def mask(value: Optional[str]) -> str:
            if not value:
                return ""
            return "****"

        from datetime import datetime
        return cls(
            id=obj.id,
            smtp_server=obj.smtp_server,
            smtp_port=int(getattr(obj, 'smtp_port', 587) or 587),
            email=getattr(obj, 'email', None),
            email_password=mask(getattr(obj, 'email_password', None)),
            phone_number=getattr(obj, 'phone_number', None),
            douyin_password=mask(getattr(obj, 'douyin_password', None)),
            xhs_cookie=mask(getattr(obj, 'xhs_cookie', None)),
            is_active=bool(getattr(obj, 'is_active', True)),
            created_at=obj.created_at.strftime('%Y-%m-%d %H:%M:%S') if getattr(obj, 'created_at', None) else '',
            updated_at=obj.updated_at.strftime('%Y-%m-%d %H:%M:%S') if getattr(obj, 'updated_at', None) else '',
        )
